package com.zhaowenhao.hello.spring.framework.aop;

import com.zhaowenhao.hello.spring.framework.aop.aspect.WHAdvice;
import com.zhaowenhao.hello.spring.framework.aop.support.WHAdvisedSupport;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * 生成代理类的工具类采用jd动态代理,同时实现了InvocationHandler
 *
 * @author zwh
 */
public class WHJdkDynamicAopProxy implements InvocationHandler {
    //support持有被代理类，和所有的通知
    private WHAdvisedSupport support;

    public WHJdkDynamicAopProxy(WHAdvisedSupport config) {
        this.support = config;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Map<String, WHAdvice> adviceMap = support.getAdvices(method, this.support.getTargetClass());
        invokeAdvice(adviceMap.get("before"));
        Object result = null;
        try {
            result = method.invoke(support.getTarget(), args);
        } catch (Exception e) {
            invokeAdvice(adviceMap.get("afterThrowing"));
        }

        invokeAdvice(adviceMap.get("after"));
        return result;
    }

    private void invokeAdvice(WHAdvice advice) {
        try {
            advice.getApsectMethod().invoke(advice.getAspect());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public Object getProxy() {
        return Proxy.newProxyInstance(support.getTargetClass().getClassLoader(), this.support.getTargetClass().getInterfaces(), this);
    }

}
